package com.kh.rationaldrugreview.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Service for extracting text from PDF files
 * Uses Apache PDFBox for text extraction
 */
@Slf4j
@Service
public class PDFTextExtractor {
    
    @PostConstruct
    public void init() {
        // Suppress PDFBox font warnings
        System.setProperty("org.apache.pdfbox.rendering.UsePureJavaCMYKConversion", "true");
        
        // Set PDFBox logging level to reduce font warnings
        Logger.getLogger("org.apache.pdfbox").setLevel(Level.SEVERE);
        Logger.getLogger("org.apache.fontbox").setLevel(Level.SEVERE);
    }
    
    /**
     * Extract text from PDF file
     * @param filePath Path to the PDF file
     * @return Extracted text content
     */
    public String extractTextFromPDF(String filePath) throws IOException {
        log.info("Extracting text from PDF: {}", filePath);
        
        // Handle file:// prefix if present
        String actualPath = filePath;
        if (filePath.startsWith("file://")) {
            actualPath = filePath.substring(7);
        } else if (filePath.startsWith("file:")) {
            actualPath = filePath.substring(5);
        }
        
        Path path = Paths.get(actualPath);
        if (!Files.exists(path)) {
            throw new IOException("PDF file not found: " + actualPath);
        }
        
        try (PDDocument document = Loader.loadPDF(new File(actualPath))) {
            PDFTextStripper stripper = new PDFTextStripper();
            
            // Configure text extraction
            stripper.setSortByPosition(true);
            stripper.setStartPage(1);
            stripper.setEndPage(document.getNumberOfPages());
            
            String text = stripper.getText(document);
            
            log.info("Successfully extracted {} characters from PDF", text.length());
            log.info("PDF has {} pages", document.getNumberOfPages());
            
            return text;
        } catch (IOException e) {
            log.error("Error extracting text from PDF: {}", e.getMessage());
            throw e;
        }
    }
    
    /**
     * Extract text from specific pages
     * @param filePath Path to the PDF file
     * @param startPage Start page (1-based)
     * @param endPage End page (1-based)
     * @return Extracted text content
     */
    public String extractTextFromPages(String filePath, int startPage, int endPage) throws IOException {
        log.info("Extracting text from PDF pages {}-{}: {}", startPage, endPage, filePath);
        
        String actualPath = filePath;
        if (filePath.startsWith("file://")) {
            actualPath = filePath.substring(7);
        } else if (filePath.startsWith("file:")) {
            actualPath = filePath.substring(5);
        }
        
        try (PDDocument document = Loader.loadPDF(new File(actualPath))) {
            PDFTextStripper stripper = new PDFTextStripper();
            
            stripper.setSortByPosition(true);
            stripper.setStartPage(startPage);
            stripper.setEndPage(Math.min(endPage, document.getNumberOfPages()));
            
            String text = stripper.getText(document);
            
            log.info("Extracted {} characters from pages {}-{}", 
                text.length(), startPage, endPage);
            
            return text;
        }
    }
    
    /**
     * Get PDF metadata and basic information
     * @param filePath Path to the PDF file
     * @return PDF information
     */
    public PDFInfo getPDFInfo(String filePath) throws IOException {
        String actualPath = filePath;
        if (filePath.startsWith("file://")) {
            actualPath = filePath.substring(7);
        } else if (filePath.startsWith("file:")) {
            actualPath = filePath.substring(5);
        }
        
        try (PDDocument document = Loader.loadPDF(new File(actualPath))) {
            PDFInfo info = new PDFInfo();
            info.setPageCount(document.getNumberOfPages());
            info.setTitle(document.getDocumentInformation().getTitle());
            info.setAuthor(document.getDocumentInformation().getAuthor());
            info.setSubject(document.getDocumentInformation().getSubject());
            info.setCreator(document.getDocumentInformation().getCreator());
            info.setFilePath(actualPath);
            info.setFileSize(Files.size(Paths.get(actualPath)));
            
            return info;
        }
    }
    
    /**
     * PDF information class
     */
    @lombok.Data
    public static class PDFInfo {
        private int pageCount;
        private String title;
        private String author;
        private String subject;
        private String creator;
        private String filePath;
        private long fileSize;
    }
}